<template>
  <div class="slider-verification" ref="sliderContainer">
    <div class="slider-left-bg" :style="sliderLeftWidthStyle"></div>
    <div class="prompt-text" :style="verifySuccess ? promptTextStyleSuccess : {}">
      {{ verifySuccess ? '验证通过' : '向右拖动滑块进行验证' }}
    </div>
    <div ref="slider" @mousedown="mouseDownHandler($event)" :class="{ 'slider-verify-success': verifySuccess }"
      class="slider" :style="sliderToLeftStyle"></div>
  </div>
</template>

<script>
import { defineComponent, ref, onMounted } from 'vue';

/**
 * 组件名称：
 * 组件描述：
 */
export default defineComponent({
  name: 'SliderVerification',
  components: {},
  props: {
    /**
     * 验证成功提示文字样式
     */
    promptTextStyleSuccess: {
      type: Object,
      default: {
        color: '#ffffff'
      }
    },
    /**
     * 验证成功需要拖动距离倍数，倍数越大验证成功需要拖动的距离越大
     */
    multiple: {
      type: Number,
      default: 2
    }
  },
  setup(props, context) {
    let sliderState = ref(false)
    let verifySuccess = ref(false)
    let beginClientX = ref(0)
    let maxWidth = ref(0)
    const slideWidth = ref(0)
    const mouseMoveHandler = (e) => {
      if (sliderState.value) {
        let width = (e.clientX - beginClientX.value) / props.multiple;
        if (width > 0 && width <= maxWidth.value) {
          slideWidth.value = width
        } else if (width > maxWidth.value) {
          slideWidth.value = maxWidth.value
          verifySuccessFun();
        }
      }
    }
    const moseUpHandler = (e) => {
      sliderState.value = false;
      let width = (e.clientX - beginClientX.value) / props.multiple;
      if (width < maxWidth.value) {
        slideWidth.value = 0
      }
    }
    const verifySuccessFun = () => {
      verifySuccess.value = true
      context.emit('statusChange', true)
      document.getElementsByTagName('html')[0].removeEventListener('mousemove', mouseMoveHandler);
      document.getElementsByTagName('html')[0].removeEventListener('mouseup', moseUpHandler);
      slideWidth.value = maxWidth.value
    }
    const slider = ref(null)
    const sliderContainer = ref(null)
    onMounted(() => {
      maxWidth.value = sliderContainer.value.offsetWidth - slider.value.offsetWidth;
      addListener()
    })
    const addListener = () => {
      document.getElementsByTagName('html')[0].addEventListener('mousemove', mouseMoveHandler);
      document.getElementsByTagName('html')[0].addEventListener('mouseup', moseUpHandler)
    }
    return {
      sliderContainer, slider,
      beginClientX, // 鼠标按下的位置
      sliderState,     // 滑块是否可以移动
      maxWidth,// 滑块验证成功需要移动的最大距离
      verifySuccess,  // 是否验证成功
      slideWidth, // 滑块滑过的区域宽度
      reset() { // 重置
        addListener()
        context.emit('statusChange', false)
        beginClientX.value = 0
        sliderState.value = false
        verifySuccess.value = false
        slideWidth.value = 0
      },
      mouseDownHandler(e) { // 鼠标在滑块上按下事件
        if (!this.verifySuccess) {
          this.sliderState = true;
          this.beginClientX = e.clientX;
        }
      },
    }
  },
  computed: {
    sliderToLeftStyle() {
      return {
        left: this.slideWidth + 'px'
      }
    },
    sliderLeftWidthStyle() {
      return {
        width: this.slideWidth + 'px'
      }
    }
  }
});
</script>
<style scoped lang="less">
.slider-verification {
  position: relative;
  background-color: #055265;
  width: 100%;
  height: 100%;
  line-height: 48px;
  text-align: center;
  user-select: none;
}

.slider {
  position: absolute;
  top: 0;
  width: 42px;
  height: 100%;
  cursor: move;
  background: rgb(0, 157, 177) url("") no-repeat center;
  background-size: 30px 30px;
}

.slider-verify-success {
  background: #8dffc9 url("") no-repeat center;
  background-size: 30px 30px;
}

//滑块滑过区域的样式
.slider-left-bg {
  background-color: rgba(0, 235, 255, 0.42);
  width: 0;
  height: 100%;
}

//提示文本样式
.prompt-text {
  position: absolute;
  top: 0;
  width: 100%;
  height: 100%;
  text-align: center;
  font-size: 14px;
  line-height: 1;
  padding: 13px;
  color: #ffffff;
  opacity: 0.7;
}
</style>

